package solutions.ferpa.ztest.intf;

import br.com.telescope.adsrt.dom.DomId;
import br.com.telescope.adsrt.dom.DomOpcao;
import br.com.telescope.adsrt.dom.DomSelectionCheck;
import br.com.telescope.adsrt.dom.DomSourceCode;
import br.com.telescope.adsrt.dom.DomTextLong;
import br.com.telescope.adsrt.dom.DomUpper;
import br.com.telescope.adsrt.lib.*;
import br.com.telescope.adsrt.lib.AdsException;
import br.com.telescope.adsrt.lib.Form;
import br.com.telescope.sql.ModelQuery;
import br.com.telescope.t2.EntityBinding;
import br.com.telescope.t2.ServiceModel;
import br.com.telescope.t2.exception.ApplicationRuntimeException;
import br.com.telescope.t2.feature.DeleteFeature;
import br.com.telescope.t2.feature.InsertFeature;
import br.com.telescope.t2.feature.ListFeature;
import br.com.telescope.t2.feature.LookupFeature;
import br.com.telescope.t2.feature.QueryFeature;
import br.com.telescope.t2.feature.UpdateFeature;
import br.com.telescope.t2.feature.ViewFeature;
import br.com.telescope.util.ObjectUtil;
import solutions.ferpa.ztest.ent.*;

/**
 * Fórmulas para execuções.
 * <p>
 * Interface para manutenção de Fórmula para execução
 * <P>
 * Telescope origin: ZTEST.CAD_FORMULA_EXECUCAO
 * <P>
 * Base entity: ZTEST.FORMULA_EXECUCAO
 * <P>
 * @author TELESCOPE - Build task T2 Web Interface Generator
 * <P>
 * @version 0.1
 */
public class CadFormulaExecucao extends ServiceModel {
    
    // <editor-fold defaultstate="collapsed" desc="Generated Code">
    public static final String GLOBAL_NAME = "ZTEST.CAD_FORMULA_EXECUCAO";
    
    @Override
    public String globalName() {
        return GLOBAL_NAME;
    }
    
    {
        setTitle("Fórmulas para execuções");
    }
    
    protected EntFormulaExecucao base;
    protected EntAplicativoOperacao aplc;
    protected EntVariavelAplicativo vrcb;
    protected EntFormulaExecucao rec; // NEED_TJW1_COMPATIBILITY
    
    // Record items
    private DomUpper aNome;
    private DomSourceCode aFormula;
    private DomTextLong aDescricao;
    private DomId aId;
    private DomId aAplicativoOperacaoId;
    private DomOpcao aAplcNome;
    private DomOpcao aAplcVersaoAplicativo;
    private DomUpper aVrcbNome;
    private DomSelectionCheck aVariaveisFormula;
    
    // Query items
    private DomSourceCode qFormula;
    private DomOpcao qAplcNome;
    private DomUpper qNome;
    
    @Override
    public String getBaseSql() {
        return "select BASE.*"
                + " , APLC.NOME as APLC_NOME"
                + " , APLC.VERSAO_APLICATIVO as APLC_VERSAO_APLICATIVO"
                + " , VRCB.NOME as VRCB_NOME"
                + " , APLC.ID as Z_APLC_ID"
                + " , VRCB.ID as Z_VRCB_ID"
                + " from FORMULA_EXECUCAO BASE"
                + " join APLICATIVO_OPERACAO APLC on APLC.ID = BASE.APLICATIVO_OPERACAO_ID"
                + " join VARIAVEL_APLICATIVO VRCB on VRCB.ID = BASE.VARIAVEL_RECEBE_VALOR_ID";
    }
    
    @Override
    public void initAttributes() {
        
        aNome = new DomUpper();
        aNome.context(ctx).name("NOME").label("Nome da fórmula");
        
        aFormula = new DomSourceCode();
        aFormula.context(ctx).name("FORMULA").label("Fórmula (expressão) ");
        
        aDescricao = new DomTextLong();
        aDescricao.context(ctx).name("DESCRICAO").label("Descrição");
        
        aId = new DomId();
        aId.context(ctx).name("ID").label("Id");
        
        aAplicativoOperacaoId = new DomId();
        aAplicativoOperacaoId.context(ctx).name("APLICATIVO_OPERACAO_ID").label("Aplicativo de operação");
        
        aAplcNome = new DomOpcao();
        aAplcNome.context(ctx).name("APLC_NOME").label("Nome do aplicativo").group(true);
        
        aAplcNome.setSqlOptions("SELECT NOME, NOME FROM APLICATIVO_OPERACAO APLC ORDER BY 1");
        
        aAplcVersaoAplicativo = new DomOpcao();
        aAplcVersaoAplicativo.context(ctx).name("APLC_VERSAO_APLICATIVO").label("Versão do aplicativo").group(true);
        
        aAplcVersaoAplicativo.setSqlOptions("SELECT VERSAO_APLICATIVO, VERSAO_APLICATIVO FROM APLICATIVO_OPERACAO APLC ORDER BY 1");
        aAplcVersaoAplicativo.setDefaultValue("1");
        
        aVrcbNome = new DomUpper();
        aVrcbNome.context(ctx).name("VRCB_NOME").label("Nome da variável");
        aVrcbNome.setListOfValuesQuery(createQuery()
                .select("*")
                .from("(SELECT NOME as valor"
                + " , NOME as pesquisar"
                + " , NOME as descricao"
                + " from VARIAVEL_APLICATIVO VRCB)", "q"));
        aVrcbNome.setAutocompleteLength(2);
        
        aVariaveisFormula = new DomSelectionCheck();
        aVariaveisFormula.context(ctx).name("VARIAVEIS_FORMULA").label("Variáveis da fórmula").unbound(true);
        
        
        qFormula = new DomSourceCode();
        qFormula.context(ctx).name("FORMULA").label("Fórmula (expressão) ");
        
        qAplcNome = new DomOpcao();
        qAplcNome.context(ctx).name("APLC_NOME").label("Nome do aplicativo");
        
        qAplcNome.setSqlOptions("SELECT NOME, NOME FROM APLICATIVO_OPERACAO APLC ORDER BY 1");
        
        qNome = new DomUpper();
        qNome.context(ctx).name("NOME").label("Nome da fórmula");
    }
    
    @Override
    public void initEntityBindings() {
        EntityBinding binding;
        
        binding = new EntityBinding("ZTEST.APLICATIVO_OPERACAO", "APLC", "Z_APLC_ID", "ZTEST.CAD_APLICATIVO_OPERACAO.VIEW");
        binding.addFields(aAplcNome, aAplcVersaoAplicativo);
        entityBindings.add(binding);
        
        binding = new EntityBinding("ZTEST.VARIAVEL_APLICATIVO", "VRCB", "Z_VRCB_ID", "ZTEST.CAD_VARIAVEL_APLICATIVO.VIEW");
        binding.addFields(aVrcbNome);
        entityBindings.add(binding);
    }
    
    @Override
    public String getQueryPkColumn() {
        return "BASE.ID";
    }
    
    @Override
    public void setId(String value) {
        this.aId.setValue(value);
    }
    
    @Override
    public EntFormulaExecucao getRecord() {
        if (base == null) {
            base = new EntFormulaExecucao(ctx);
            rec = base;
        }
        return this.base;
    }
    
    @Override
    public String getContextName() {
        return aNome.toText();
    }
    
    @Override
    public String getDefaultOrderBy() {
        return "NOME, APLC_NOME, APLC_VERSAO_APLICATIVO, VRCB_NOME";
    }
    
    @Override
    public void translateInsertFks(Form form) {
        ModelQuery query;
        
        // APLICATIVO_OPERACAO_ID
        try {
            if (form.hasFields("APLC_NOME")) {
                query = createQuery()
                        .select("APLC.ID")
                        .from("APLICATIVO_OPERACAO", "APLC")
                        .filter("APLC.NOME", form.get("APLC_NOME"))
                        ;
                base.setAplicativoOperacaoId(ObjectUtil.toLong(translateFk(query)));
            }
        } catch (AdsException ex) {
            throw new RuntimeException(ex);
        }
        
        // VARIAVEL_RECEBE_VALOR_ID
        try {
            if (form.hasFields("VRCB_NOME")) {
                query = createQuery()
                        .select("VRCB.ID")
                        .from("VARIAVEL_APLICATIVO", "VRCB")
                        .filter("VRCB.NOME", form.get("VRCB_NOME"))
                        ;
                base.setVariavelRecebeValorId(ObjectUtil.toLong(translateFk(query)));
            }
        } catch (AdsException ex) {
            throw new RuntimeException(ex);
        }
    }
    
    @Override
    public void translateUpdateFks(Form form) {
        ModelQuery query;
        
        // APLICATIVO_OPERACAO_ID
        try {
            if (form.hasFields("APLC_NOME")) {
                query = createQuery()
                        .select("APLC.ID")
                        .from("APLICATIVO_OPERACAO", "APLC")
                        .filter("APLC.NOME", form.get("APLC_NOME"))
                        ;
                base.setAplicativoOperacaoId(ObjectUtil.toLong(translateFk(query)));
            }
        } catch (AdsException ex) {
            throw new RuntimeException(ex);
        }
        
        // VARIAVEL_RECEBE_VALOR_ID
        try {
            if (form.hasFields("VRCB_NOME")) {
                query = createQuery()
                        .select("VRCB.ID")
                        .from("VARIAVEL_APLICATIVO", "VRCB")
                        .filter("VRCB.NOME", form.get("VRCB_NOME"))
                        ;
                base.setVariavelRecebeValorId(ObjectUtil.toLong(translateFk(query)));
            }
        } catch (AdsException ex) {
            throw new RuntimeException(ex);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="QUERY">
    public class FQuery extends QueryFeature {
        
        @Override
        public void initForm() {
            addField(qNome, "opt");
            addField(qAplcNome, "opt");
            addField(qFormula, "opt");
        }
        
        {
            setFeatureName("QUERY");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="LIST">
    public class FList extends ListFeature {
        
        @Override
        public void initForm() {
            addField(aNome, "view");
            addField(aAplcNome, "view");
            addField(aAplcVersaoAplicativo, "view");
            addField(aVrcbNome, "view");
            addField(aFormula, "view");
        }
        
        {
            setFeatureName("LIST");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="VIEW">
    public class FView extends ViewFeature {
        
        @Override
        public void initForm() {
            addField(aNome, "view");
            addField(aAplcNome, "view");
            addField(aAplcVersaoAplicativo, "view");
            addField(aVrcbNome, "view");
            addField(aFormula, "view");
            addField(aDescricao, "view");
            addField(aVariaveisFormula, "view");
        }
        
        @Override
        public void preDisplay() {
            try {
                preencherListaVariaveis();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("VIEW");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="INSERT">
    public class FInsert extends InsertFeature {
        
        @Override
        public void initForm() {
            aNome.setOptional(false);
            addField(aNome, "rqd");
            aAplcNome.setOptional(false);
            addField(aAplcNome, "rqd");
            aAplcVersaoAplicativo.setEditable(false);
            addField(aAplcVersaoAplicativo, "view");
            aVrcbNome.setOptional(false);
            addField(aVrcbNome, "rqd");
            aFormula.setOptional(false);
            addField(aFormula, "rqd");
            addField(aDescricao, "opt");
            addField(aVariaveisFormula, "opt");
        }
        
        @Override
        public void preDisplay() {
            try {
                preencherListaVariaveis();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("INSERT");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="UPDATE">
    public class FUpdate extends UpdateFeature {
        
        @Override
        public void initForm() {
            aNome.setOptional(false);
            addField(aNome, "rqd");
            aAplcNome.setOptional(false);
            addField(aAplcNome, "rqd");
            aAplcVersaoAplicativo.setEditable(false);
            addField(aAplcVersaoAplicativo, "view");
            aVrcbNome.setOptional(false);
            addField(aVrcbNome, "rqd");
            aFormula.setOptional(false);
            addField(aFormula, "rqd");
            addField(aDescricao, "opt");
            addField(aVariaveisFormula, "opt");
        }
        
        @Override
        public void preDisplay() {
            try {
                preencherListaVariaveis();
            } catch (AdsException ex) {
                throw new ApplicationRuntimeException(ex);
            }
        }
        
        {
            setFeatureName("UPDATE");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="DELETE">
    public class FDelete extends DeleteFeature {
        
        @Override
        public void initForm() {
            addField(aNome, "view");
            addField(aAplcNome, "view");
            addField(aFormula, "view");
        }
        
        {
            setFeatureName("DELETE");
            setPrimary(false);
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="APLC_NOME_LOOKUP">
    public class FAplcNomeLookup extends LookupFeature {
        
        @Override
        public void initForm() {
            aAplcNome.setEditable(true);
            addField(aAplcNome, "opt");
            aAplcVersaoAplicativo.setEditable(false);
            addField(aAplcVersaoAplicativo, "view");
        }
        
        @Override
        public ModelQuery getLookupQuery() {
            return createQuery()
                    .select("APLC.NOME as APLC_NOME")
                    .select("APLC.VERSAO_APLICATIVO as APLC_VERSAO_APLICATIVO")
                    .from("APLICATIVO_OPERACAO", "APLC")
                    ;
        }
        
        {
            setFeatureName("APLC_NOME_LOOKUP");
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="VRCB_NOME_LOOKUP">
    public class FVrcbNomeLookup extends LookupFeature {
        
        @Override
        public void initForm() {
            aVrcbNome.setEditable(true);
            addField(aVrcbNome, "opt");
        }
        
        @Override
        public ModelQuery getLookupQuery() {
            return createQuery()
                    .select("VRCB.NOME as VRCB_NOME")
                    .from("VARIAVEL_APLICATIVO", "VRCB")
                    ;
        }
        
        {
            setFeatureName("VRCB_NOME_LOOKUP");
        }
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="initFeatures">
    
    @Override
    protected void initFeatures() {
        addFeature(new FQuery());
        addFeature(new FList());
        addFeature(new FView());
        addFeature(new FInsert());
        addFeature(new FUpdate());
        addFeature(new FDelete());
        addFeature(new FAplcNomeLookup());
        addFeature(new FVrcbNomeLookup());
        super.initFeatures();
    }
    
    @Override
    public String getDefaultFeature() {
        return "QUERY";
    }
    // </editor-fold>
    
    // <editor-fold defaultstate="collapsed" desc="Getters and Setters">
    
    public String getNome() {
        return aNome.getValue();
    }
    
    public void setNome(String value) {
        this.aNome.setValue(value);
    }
    
    public String getFormula() {
        return aFormula.getValue();
    }
    
    public void setFormula(String value) {
        this.aFormula.setValue(value);
    }
    
    public String getDescricao() {
        return aDescricao.getValue();
    }
    
    public void setDescricao(String value) {
        this.aDescricao.setValue(value);
    }
    
    @Override
    public Long getId() {
        return aId.getValue();
    }
    
    public void setId(Long value) {
        this.aId.setValue(value);
    }
    
    public Long getAplicativoOperacaoId() {
        return aAplicativoOperacaoId.getValue();
    }
    
    public void setAplicativoOperacaoId(Long value) {
        this.aAplicativoOperacaoId.setValue(value);
    }
    
    public String getAplcNome() {
        return aAplcNome.getValue();
    }
    
    public void setAplcNome(String value) {
        this.aAplcNome.setValue(value);
    }
    
    public String getAplcVersaoAplicativo() {
        return aAplcVersaoAplicativo.getValue();
    }
    
    public void setAplcVersaoAplicativo(String value) {
        this.aAplcVersaoAplicativo.setValue(value);
    }
    
    public String getVrcbNome() {
        return aVrcbNome.getValue();
    }
    
    public void setVrcbNome(String value) {
        this.aVrcbNome.setValue(value);
    }
    
    public String getVariaveisFormula() {
        return aVariaveisFormula.getValue();
    }
    
    public void setVariaveisFormula(String value) {
        this.aVariaveisFormula.setValue(value);
    }
    public String getQueryNome() {
        return qNome.getQueryValue();
    }
    
    public void setQueryNome(String value) {
        this.qNome.setQueryValue(value);
    }
    public String getQueryAplcNome() {
        return qAplcNome.getQueryValue();
    }
    
    public void setQueryAplcNome(String value) {
        this.qAplcNome.setQueryValue(value);
    }
    public String getQueryFormula() {
        return qFormula.getQueryValue();
    }
    
    public void setQueryFormula(String value) {
        this.qFormula.setQueryValue(value);
    }
    // </editor-fold>
    
    /**
     * Preencher a lista de variáveis.
     */
    private void preencherListaVariaveis() throws AdsException {
        // <user-code id="20968778" parentId="20968734" hashcode="31651fa3" length="644">
        aVariaveisFormula.addSqlOptions(
                "select vf.id"
                + " ,va.nome" 
                + " ,null"
                + " from variavel_utilizada_formula vf"
                + " join variavel_aplicativo va on va.id = vf.variavel_execucao_id"
                + " order by va.nome"
                );
        
        
        EntVariavelUtilizadaFormula variavelFormula = rec.findAllVariavelUtilizadaFormulaFormulaExecucao();
        StringBuilder out = new StringBuilder(100);
        
        while (variavelFormula.next()) {
            if (out.length() > 0) out.append(",");
            out.append(variavelFormula.findVariavelExecucao().valueOfNome());
        }
        variavelFormula.close();
        aVariaveisFormula.setValue(out.toString());
        // </user-code>
    }
    
    /**
     * Salvar variáveis da fórmula.
     */
    private void salvarVariaveisFormula() throws AdsException {
        // <user-code id="20968795" parentId="20968742" hashcode="61aec9f4" length="1387">
        EntVariavelUtilizadaFormula variaveis = new EntVariavelUtilizadaFormula(ctx);
        /*
        variavelFormula.del("select id" +
                " from variavel_utilizada_formula" +
                " where formula_execucao_id = " + getRecord().valueOfId());
        String[] ids = aVariaveisFormula.getValue().split(",");
        for (String id : ids) {
            if (id.length()>0) {
                variavelFormula.nullifyId();
                variavelFormula.setFormulaExecucaoId(getRecord().valueOfId());
                variavelFormula.setVariavelExecucaoId(id);
                variavelFormula.ins();
            }
        }
        */
        
        // Excluir os que não existem...
        variaveis.del("select vruf.id" +
                " from variavel_utilizada_formula vruf" +
                " join operacoes_sistemas os on os.id = opfu.operacao_id" +
                " where vruf.formula_execucao_id = " + rec.valueOfId() +
                " and vruf.variavel_execucao_id not in (" + aVariaveisFormula.getValue() + ")");
        
        // Incluir os que faltam ser incluidos
        String[] list = aVariaveisFormula.getValue().split(",");
        for (String sid: list) {
            long variavelId = Long.parseLong(sid);
            try {
                variaveis.findByFormulaExecucaoIdVariavelExecucaoId(rec.valueOfId(), variavelId);
            } catch (RecordNotFoundException ex) {
                variaveis.nullify();
                variaveis.setFormulaExecucaoId(rec.valueOfId());
                variaveis.setVariavelExecucaoId(variavelId);
                variaveis.ins();
            }
        }
        // </user-code>
    }
    
    @Override
    public String getJsServiceFile() {
        return "ui/ztest/cad_formula_execucao.js";
    }
}
